<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8"/>
    <title>SQLTable</title>

    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/css/pluginsCss.css'/>
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/plugins.css'/>
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/css/luckysheet.css'/>
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/assets/iconfont/iconfont.css'/>
    <script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/js/plugin.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js"></script>


    <script src="./luckysheet/js/axios-0.18.0.js"></script>
    <script src="./luckysheet/js/vue.js"></script>

    <!-- 引入样式 -->
    <link rel="stylesheet" href="./luckysheet/css/index.css">
    <!-- 引入组件库 -->
    <script src="./luckysheet/js/index.js"></script>
    <script src="./luckysheet/js/url.js"></script>

</head>
<body>

<div id="app">
    <div>
        {{tname}}
        <el-date-picker
                v-model="time"
                type="month"
                value-format="yyyy-MM"
                placeholder="选择期间">
        </el-date-picker>
        <el-select
                v-model="oid"
                multiple
                collapse-tags
                :clearable="true"
                style="margin-left: 20px;width: 380px"
                placeholder="请选择组织">
            <el-option
                    v-for="item in organizationList"
                    :key="item.name"
                    :label="item.name"
                    :value="item.name">
            </el-option>
        </el-select>
        <el-button type="primary" size="small" @click="getTemplateData" round>查询</el-button>
        <el-button type="primary" size="small" @click="getTemplateData(false);outFlag=true" round>修改公式</el-button>
        <el-button type="primary" size="small" @click="saveData()" round>保存</el-button>
        <el-button type="info" style="float: right" size="small" @click="call" round>返回</el-button>
        <el-button type="primary" style="float: right;margin-right: 10px" size="small" @click="drawer = true" round>条件
        </el-button>
    </div>
    <div style="width: 100%;height: 90vh;margin-top: 10px">
        <div id="luckysheet"
             style="margin:0px;padding:0px;width:100%;height: 100%"></div>
    </div>

    <el-drawer
            title="sql配置"
            size="40%"
            :wrapper-closable="false"
            :visible.sync="drawer">
        <el-form label-position="right" label-width="100px" style="margin-right: 50px">
            <el-row>
                <el-col :span="12">
                    <el-form-item label="数据库类型">
                        <el-select v-model="formData.driver" placeholder="请选择数据库类型" clearable>
                            <el-option label="Mysql" value="0"></el-option>
                            <el-option label="Oracle" value="1"></el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="连接地址">
                        <el-input v-model="formData.url"/>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="12">
                    <el-form-item label="用户名">
                        <el-input v-model="formData.username"/>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="密码">
                        <el-input type="password" v-model="formData.password"/>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row v-for="item,index in formData.blockDataShow">
                <el-divider content-position="left">{{index+1}}段SQL配置</el-divider>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="数据块名称">
                            <el-input v-model="item.name"/>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">

                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="24">
                        <el-form-item label="sql">
                            <el-input type="textarea" v-model="item.sql"/>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="填报表名">
                            <el-input v-model="item.tableName"/>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">

                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="24">
                        <el-form-item label="字段映射">
                            <el-table
                                    height="250"
                                    :data="item.mapping"
                                    style="width: 100%">
                                <el-table-column prop="mappingField" label="映射字段" align="center">
                                    <template slot-scope="scope">
                                        <el-input v-model="scope.row.mappingField"/>
                                    </template>
                                </el-table-column>
                                <el-table-column prop="field" label="存储字段" align="center">
                                    <template slot-scope="scope">
                                        <el-input v-model="scope.row.field"/>
                                    </template>
                                </el-table-column>
                                <el-table-column
                                        label="是否主键">
                                    <template slot-scope="scope">
                                        <el-select v-model="scope.row.flag" placeholder="是否是主键">
                                            <el-option label="是" value="1"></el-option>
                                            <el-option label="否" value="0"></el-option>
                                        </el-select>
                                    </template>
                                </el-table-column>
                                <el-table-column
                                        label="操作"
                                        width="80">
                                    <template slot-scope="scope">
                                        <el-button type="danger" size="small"
                                                   @click="deleteMapping(item.mapping,scope.row)" round>
                                            删除
                                        </el-button>
                                    </template>
                                </el-table-column>

                            </el-table>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="24">
                        <el-button style="float: right;margin-right: 10px" type="danger"
                                   @click="deleteConfiguration(index)">删除配置组
                        </el-button>
                        <el-button style="float: right;margin-right: 10px" type="primary"
                                   @click="createMapping(item.mapping)">新增映射
                        </el-button>
                    </el-col>
                </el-row>
            </el-row>
            <el-divider content-position="left">操作</el-divider>
            <el-row style="margin-bottom: 10px">
                <el-col :span="24">
                    <el-button style="float: right" type="success" @click="getTemplateData()">查询</el-button>
                    <el-button style="float: right;margin-right: 10px" type="primary" @click="output()">输出该类表
                    </el-button>
                    <el-button style="float: right;margin-right: 10px" type="info" @click="addConfiguration()">添加配置组
                    </el-button>
                </el-col>
            </el-row>
        </el-form>
    </el-drawer>

</div>

<script>
    var vue = new Vue({
        el: '#app',
        data: {
            //输出标记，为真允许修改
            outFlag: false,

            options: {},
            token: {
                headers: {
                    'Authorization': "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzMSJdLCJ1c2VyX25hbWUiOiJrdWlodWEwMDEiLCJzY29wZSI6WyJhbGwiXSwiZXhwIjoxNjM3ODQ3NzA1LCJhdXRob3JpdGllcyI6WyJPLTEiLCJSLWhlYWRPZmZpY2UiXSwianRpIjoiNzhhNTA1NDctZDQwNy00NDllLTgzOTMtNDJjNzRiMTRlZTM2IiwiY2xpZW50X2lkIjoiYzEifQ.NomK7mgD8Kqk0RECH8YJZm9u4p2W-eITBriE9xeNzmM"
                }
            },
            luckysheet: "",
            drawer: false,
            formData: {
                driver: "",
                url: "",
                username: "",
                password: "",
                blockDataShow: [],
                blockData: []
            },
            organizationList: [],

            //数据块列表
            blockDataList: [],
            //数据块详情
            blockDataDetailsList: [],

            tid: 288,
            oid: [],
            oname: "",
            time: "",
            tname: "测试",

            backendUrl: "http://127.0.0.1:18082",
        },
        created() {
            this.backendUrl = window.backendUrl
            Request = this.GetRequest();
            this.token = {
                headers: {
                    'Authorization': Request.token
                }
            }
            this.tid = Request.tid;
            this.tname = Request.tname;

            axios.get(this.backendUrl + "/organization", this.token).then((res) => {

                this.organizationList = res.data.data

            }).catch((err) => {
                console.log(err);
            });

            // 查询模板数据
            this.getTemplateData()

            this.$notify.info({
                title: '提示',
                dangerouslyUseHTMLString: true,
                message: '<span>' + "点击" + "<span style='color:blue'>" + "条件" + "</span>" + "进行sql配置" + '</span>',
                position: 'bottom-left',
            });
        },
        mounted: function () {

        },
        methods: {

            //参数初始化
            optionsS() {
                this.options = {
                    container: 'luckysheet',
                    title: 'Luckysheet Demo',
                    lang: 'zh', // 设定表格语言
                    row: 36, //行数
                    column: 18, //列数
                    // 是否显示工具栏
                    showtoolbar: false,
                    // 是否显示顶部信息栏
                    showinfobar: false,
                    // 是否显示sheet页签
                    showsheetbar: false,
                    // 是否显示公式栏
                    sheetFormulaBar: false,
                    // 是否允许新增行
                    enableAddRow: false,
                    // 是否允许返回顶部
                    enableAddBackTop: false,
                    hook: {
                        cellUpdateBefore: this.cellUpdateBefore
                        // cellUpdated: "",
                        // cellUpdateBefore: ""
                    },
                    data: [{
                        // sheet名
                        name: "sheet1",
                        defaultColWidth: 150, //自定义列宽
                        index: "0",
                        config: {
                            // 单元格合并配置
                            "merge": {},
                            // 单元格边框配置
                            "borderInfo": [{
                                "rangeType": "range",
                                "borderType": "border-all",
                                "style": "1",
                                "color": "#000000",
                                "range": [{
                                    "row": [7, 8],
                                    "column": [2, 3]
                                }]
                            }],
                        },
                        // 单元格数据配置
                        celldata: [],
                        calcChain: []
                    }],
                }
            },

            //单元格编辑回调函数
            cellUpdateBefore(r, c, value, isRefresh) {
                // 查询修改数据所在数据块
                blockDataDetailsList = this.blockDataDetailsList
                blockDataDetailsList.forEach((value, index, array) => {
                    if (value.dataS <= r && value.dataE >= r) {
                        blockDataDetailsList[index].flag = true
                    }
                })
            },

            GetRequest() {
                var url = location.search; //获取url中"?"符后的字串

                var theRequest = new Object();
                if (url.indexOf("?") != -1) {
                    var str = url.substr(1);
                    strs = str.split("&");
                    for (var i = 0; i < strs.length; i++) {
                        theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]);
                    }
                }
                return theRequest;
            },
            // 获取表内数据
            getAll() {
                var list = luckysheet.getluckysheetfile()[0].data
            },

            // 查询模板数据
            getTemplateData(flag = true) {
                //重置数据块详情
                this.blockDataDetailsList = []

                // 是否查询sql数据，flag==true查询，否则不查询
                axios.get(this.backendUrl + "/template/findByPid/" + this.tid, this.token).then((res) => {

                    if (res.data.data[0].rowId == -1) {
                        // 判断是否含有sql语句
                        data = res.data.data[0].data.slice(1, -1)
                        configuration = data.replace(/~/g, "'")
                        configuration = JSON.parse(configuration)
                        this.formData = configuration

                        if (flag) {
                            this.outFlag = false
                            //    初始化数据块
                            this.findSQL(res.data.data.slice(1,))
                        } else {
                            var dataList = []
                            res.data.data.slice(1,).forEach(element => {
                                dataList.push(eval('(' + element.data + ')'))
                            })
                            this.findSourceBody(dataList)
                        }
                    }else {
                        var dataList = []
                        res.data.data.forEach(element => {
                            dataList.push(eval('(' + element.data + ')'))
                        })
                        this.findSourceBody(dataList)
                    }

                }).catch((err) => {
                    console.log(err);
                });
            },

            // 处理数据体（sql处理完毕之后）
            dataBodyManage(dataListS, blockDataList) {

                let sourceList = []
                var blockDataName = null
                //数据块结构
                var blockDataConstruction = []
                //公式结束标记块
                var formulaflag = false

                //数据块开始标记(数据块从哪行开始)
                var dataS = 0;
                //数据块结束标记(数据块在那行结束)
                var dataE = 0;

                dataListS.forEach((element, index1, array1) => {
                    var dataList = eval('(' + element.data + ')')

                    //判断改行是否是数据块
                    dataList.forEach((value, index, array) => {
                        value = value + ""

                        if (value.indexOf("[") == 0) {
                            blockDataName = value.split("(")[0].slice(1,)
                            dataList[index] = value.split("(")[1]
                        }
                        if (value.indexOf("]") != -1) {
                            formulaflag = true
                            dataList[index] = value.slice(0, -2)
                        }
                    })

                    // 判断是否是数据块，是数据块则构建数据块格式，否则直接添加
                    if (blockDataName == null) {
                        //    非数据块数据
                        sourceList.push(dataList)
                    } else {
                        //    是数据块
                        blockDataConstruction.push(dataList)
                        if (formulaflag) {
                            dataList = this.processingBlocks(blockDataName, blockDataConstruction, blockDataList)

                            // 记录数据块起始位置
                            dataS = sourceList.length;

                            dataList.forEach((value => {
                                sourceList.push(value)
                            }))

                            // 记录数据块结束位置
                            dataE = dataS + dataList.length - 1;
                            // 记录数据块详细信息
                            this.blockDataDetailsList.push({
                                dataS: dataS,        //数据块开始行
                                dataE: dataE,        //数据块结束行
                                formulaStructure: blockDataConstruction,     //数据块格式
                                blockDataName: blockDataName     //数据块名称
                            })

                            // 重置数据块结构
                            blockDataConstruction = []
                            //    本次数据块结束,重置数据块变量
                            blockDataName = null;
                            formulaflag = false;
                        }
                    }
                })

                //    渲染数据
                this.findSourceBody(sourceList)
            },


            // 处理数据块为正式数据，并返回处理后数据
            processingBlocks(blockDataName, blockDataConstruction, blockDataList) {
                var blockData = null
                //    取出数据块真实数据
                blockDataList.forEach(((value, index, array) => {
                    if (value["name"] == blockDataName) {
                        blockData = value["data"]
                    }
                }))

                var dataLast = []
                blockData.forEach(((value, index, array) => {
                    var objString = JSON.stringify(blockDataConstruction);
                    var obj2 = JSON.parse(objString);
                    obj2.forEach(((value1, index1, array1) => {
                        value1.forEach(((value2, index2, array2) => {
                            obj2[index1][index2] = (value[value2] != undefined && value[value2] != null) ? value[value2] : ""
                        }))
                        dataLast.push(obj2[index1])
                    }))
                }))
                return dataLast
            },


            // 查询源数据
            findSourceBody(lastDataList) {

                this.optionsS()

                let sourceList = lastDataList

                // 设置表格大小
                this.options.column = sourceList[0].length;
                this.options.row = sourceList.length;

                // 设置边框范围
                this.options.data[0].config["borderInfo"][0]["range"][0]["row"] = [0, sourceList.length - 1]
                this.options.data[0].config["borderInfo"][0]["range"][0]["column"] = [0, sourceList[0].length - 1]

                for (var i = 0; i < sourceList.length; i++) {
                    for (var j = 0; j < sourceList[i].length; j++) {
                        var item = {}
                        var gs = {}

                        if ((sourceList[i][j] + "").substring(0, 1) == "=") {

                            item = {
                                "r": i,
                                "c": j,
                                "v": {

                                    "ct": {"fa": 'General', "t": 'g'},
                                    "f": sourceList[i][j].split("&")[0].replace(/\$/g, '"'),
                                    "ht": 1,
                                    "m": sourceList[i][j].split("&")[1],
                                    "v": sourceList[i][j].split("&")[1],
                                },
                            }

                            gs = {
                                "r": i,
                                "c": j,
                                "index": "0",
                                "func": [
                                    true,
                                    sourceList[i][j].split("&")[1],
                                    sourceList[i][j].split("&")[0].replace(/\$/g, '"')
                                ],
                                "color": "w",
                                "parent": null,
                                "chidren": {},
                                "times": 0
                            }

                            this.options.data[0].calcChain.push(gs)
                        } else {
                            item = {
                                "r": i,
                                "c": j,
                                "v": {
                                    "ct": {
                                        "fa": "General",
                                        "t": "n"
                                    },
                                    "v": sourceList[i][j],
                                    "m": sourceList[i][j],
                                    "vt": 0,
                                    "ht": 1
                                },
                            }
                        }

                        this.options.data[0].celldata.push(item)
                    }
                }

                luckysheet.create(this.options);

            },

            //    保存变更后数据
            save() {
                //    获取模板数据
                data_list = luckysheet.getSheetData(0)

                for (const row_index in data_list) {
                    for (const col_index in data_list[row_index]) {
                        if (data_list[row_index][col_index] != null && data_list[row_index][col_index].hasOwnProperty('f')) {
                            data_list[row_index][col_index] = data_list[row_index][col_index].f + "&" + data_list[row_index][col_index].v

                            data_list[row_index][col_index] = data_list[row_index][col_index].replace(/"/g, '$');
                        } else if (data_list[row_index][col_index] != null && data_list[row_index][col_index].hasOwnProperty('v')) {
                            data_list[row_index][col_index] = data_list[row_index][col_index].v
                        } else {
                            data_list[row_index][col_index] = ""
                        }
                    }
                }

                // 组装更改对象
                for (const row_index in data_list) {
                    data_list[row_index] = {
                        "pid": this.tid,
                        "data": JSON.stringify(data_list[row_index]),
                        "rowId": row_index
                    };
                }

                configuration = JSON.stringify(this.formData).replace(/'/g, "~")
                data_list.push({
                    "pid": this.tid,
                    "data": JSON.stringify(configuration),
                    "rowId": -1
                })

                axios.post(this.backendUrl + "/template/alterTemplate", data_list, this.token).then((res) => {

                    this.$message({
                        message: res.data.message,
                        type: res.data.flag ? "success" : "error"
                    });

                }).catch((err) => {
                    console.log(err);
                });
            },

            openFullScreen2() {
                const loading = this.$loading({
                    lock: true,
                    text: 'Loading',
                    spinner: 'el-icon-loading',
                    background: 'rgba(0, 0, 0, 0.7)'
                });
                return loading;
            },

            //sql查询
            findSQL(dataListS) {

                //重置sql列表
                this.formData.blockData = []
                //重置数据块列表
                this.blockDataList = []

                // 判断公式是否为空
                if (this.oid.length == 0) {
                    for (let index in this.organizationList) {
                        this.oid.push(this.organizationList[index]["name"])
                    }
                }

                let gs = ""

                for (let index in this.oid) {
                    gs = gs + "'" + this.oid[index] + "'" + ","
                }

                gs = gs.slice(0, -1)

                this.oname = gs

                var blockDataList = this.blockDataList

                // 时间变量${time}  单位变量${unit}
                let blockDataShow = this.formData.blockDataShow

                for (let i = 0; i < blockDataShow.length; i++) {
                    this.formData.blockData.push(this.parameterReplace(blockDataShow[i].sql, ["{time}", "{oname}"]))
                }

                //开启遮罩层
                var loading = this.openFullScreen2()

                axios.post(this.backendUrl + "/jdbc", this.formData, this.token).then((res) => {

                    var resDataList = res.data.data

                    // 初始化数据块
                    this.formData.blockDataShow.forEach((value, index, array) => {
                        blockDataList.push({name: value.name, data: resDataList[index]});
                    })

                    console.log(dataListS)
                    console.log(blockDataList)
                    this.dataBodyManage(dataListS, blockDataList)

                }).catch((err) => {

                    this.$notify.error({
                        title: '查询失败',
                        dangerouslyUseHTMLString: true,
                        message: '<span>' + this.formData.sql + '</span>',
                        position: 'top-left',
                        duration: 0
                    });

                    console.log(err);
                }).finally(() => {
                    loading.close();
                })
            },

            // 参数替换方法
            parameterReplace(sql, paramList) {
                //遍历参数列表
                for (const paramListKey in paramList) {
                    paramCrude = paramList[paramListKey]
                    //获取参数名
                    param = paramCrude.slice(1, -1)
                    while (true) {
                        if (sql.indexOf(paramCrude) == -1) {
                            break
                        } else {
                            sql = sql.replace(paramCrude, this[param])
                        }
                    }
                }
                return sql;
            },

            select() {
                this.findSQL()
            },

            //添加配置组
            addConfiguration() {
                try {
                    this.formData.blockDataShow.push({
                        sql: "",
                        name: "",
                        tableName: "",
                        mapping: []
                    })
                } catch (errnoError) {
                    // 配置不规范
                    this.formData = {
                        driver: "",
                        url: "",
                        username: "",
                        password: "",
                        blockDataShow: [],
                        blockData: []
                    },
                        this.formData.blockDataShow.push({
                            sql: "",
                            name: "",
                            tableName: "",
                            mapping: []
                        })
                }
                console.log(this.formData)
            },

            //删除配置组
            deleteConfiguration(index) {
                this.formData.blockDataShow.splice(index, 1);
            },

            // 输出该类表
            output() {
                if (!this.outFlag) {
                    this.$message({
                        type: 'error',
                        message: '请切换至公式修改在进行此操作'
                    });
                    return
                }

                this.$confirm('此操作将覆盖模板样式, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.save()
                }).catch((err) => {
                    this.$message({
                        type: 'info',
                        message: '已取消输出'
                    });
                });
            },

            //新增映射
            createMapping(mapping) {
                mapping.push({field: "",mappingField:"" ,flag: "1", key: Math.random()})
            },

            //删除映射
            deleteMapping(mapping, row) {
                for (var i = 0; i < mapping.length; i++) {
                    if (mapping[i].key == row.key) {
                        mapping.splice(i, 1);
                    }
                }
            },

            // 保存填报数据
            saveData() {
                //切换至数据进行保存
                if (this.outFlag) {
                    this.$message({
                        type: 'error',
                        message: '切换至数据进行保存'
                    });
                    return
                }
                var data_body = [];
                this.blockDataDetailsList.forEach(value => {
                    if (value.flag) {
                        data_body.push(this.fitTogetherData(value))
                    }
                })

                //判断是否存在填报数据
                if (data_body.length == 0) {
                    this.$message({
                        type: 'warning',
                        message: '未修改填报数据'
                    });
                    return
                }

            //    数据都准备完毕，开始装配最终数据
                var data_last = {
                //    数据源类型
                    driverName:this.formData.driver,
                //    数据源地址
                    url:this.formData.url,
                //    用户名
                    username:this.formData.username,
                //    密码
                    password:this.formData.password,
                //    数据体数组对象
                    data:data_body,
                }

                //    携带数据发送请求
                console.log(data_last)

                //开启遮罩层
                var loading = this.openFullScreen2()

                axios.post(this.backendUrl + "/jdbc/reportForm", data_last, this.token).then((res) => {

                    console.log(res.data)

                    this.$message({
                        message: res.data.message.replace(/&/g, '\r\n'),
                        type: res.data.flag ? "success" : "error"
                    });

                }).catch((err) => {

                    this.$notify.error({
                        title: '保存失败',
                        dangerouslyUseHTMLString: true,
                        message: '<span>' + this.formData.sql + '</span>',
                        position: 'top-left',
                        duration: 0
                    });

                    console.log(err);
                }).finally(() => {
                    loading.close();
                })
            },

            //根据数据块装配最终数据
            fitTogetherData(blockDataDetails) {
                var mapping = null;
                var tablename = null;
                //找到数据块映射
                this.formData.blockDataShow.forEach(value => {
                    if (value.name == blockDataDetails.blockDataName) {
                        mapping = value.mapping
                        tablename = value.tableName
                    }
                })

                //截取数据块有效数据
                var data_list = luckysheet.getSheetData(0).slice(blockDataDetails.dataS, blockDataDetails.dataE + 1);

                for (const row_index in data_list) {
                    for (const col_index in data_list[row_index]) {
                        if (data_list[row_index][col_index] != null && data_list[row_index][col_index].hasOwnProperty('f')) {
                            data_list[row_index][col_index] = data_list[row_index][col_index].f + "&" + data_list[row_index][col_index].v

                            data_list[row_index][col_index] = data_list[row_index][col_index].replace(/"/g, '$');
                        } else if (data_list[row_index][col_index] != null && data_list[row_index][col_index].hasOwnProperty('v')) {
                            data_list[row_index][col_index] = data_list[row_index][col_index].v
                        } else {
                            data_list[row_index][col_index] = ""
                        }
                    }
                }

                //根据数据块框架分割有效数据（方便组装）
                var formulaStructure = blockDataDetails.formulaStructure

                var dataLast = []
                for (var i = 0, len = data_list.length; i < len; i += formulaStructure.length) {
                    dataLast.push(data_list.slice(i, i + formulaStructure.length));
                }

                var coordinateList = []
                //根据映射取出相应的位置(为下一步正式数据装配做准备)
                for (let i = 0; i < formulaStructure.length; i++) {
                    for (let j = 0; j < formulaStructure[i].length; j++) {
                        if (formulaStructure[i][j] != "") {
                            for (let k = 0; k < mapping.length; k++) {
                                if (mapping[k].mappingField == formulaStructure[i][j]) {
                                    coordinate = {
                                        x: j,
                                        y: i,
                                        flag: mapping[k].flag,
                                        field: mapping[k].field
                                    }
                                    coordinateList.push(coordinate)
                                }
                            }
                        }
                    }
                }

                //填报后的数据集合
                var data_body = []
                // 开始装配数据
                dataLast.forEach(dataLastValue => {
                    var data = []
                    coordinateList.forEach(coordinateValue => {
                        data.push(dataLastValue[coordinateValue.y][coordinateValue.x])
                    })
                    data_body.push(data)
                })

                //字段信息装配
                var field_body = []
                coordinateList.forEach(coordinateValue => {
                    field_body.push({
                        key: coordinateValue.field,
                        flag: coordinateValue.flag,
                    })
                })

                return {
                    tablename: tablename,
                    field: field_body,
                    value: data_body,
                }
            },

            call() {
                window.open("call=binding.template_bind.bind=back")
            },
        }
    })
</script>
</body>
</html>